package com.jsd.demo.controller;

import com.gogbuy.api.net.OpenApiNetService;
import com.jsd.demo.utils.DateFormatUtil;
import com.jsd.demo.utils.StringUtils;
import com.jsd.demo.utils.UppCore;
import com.jsd.demo.vo.PayParamVO;
import com.jsd.demo.vo.PayQueryVO;
import com.jsd.demo.vo.RefundVO;
import com.jsd.demo.vo.WithdrawalVO;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 统一支付回调
 */
@RestController
@RequestMapping("/")
@Slf4j
public class JsdPayDemoController {

    @Value("${upp.jsdSavePayParam}")
    private String jsdSavePayParamUrl;

    @Value("${upp.jsdPayQuery}")
    private String jsdPayQueryUrl;

    @Value("${upp.jsdRefund}")
    private String jsdRefundUrl;

    @Value("${upp.jsdWithdrawal}")
    private String jsdWithdrawalUrl;

    @Value("${upp.cashStageMerchantId}")
    private String cashStageMerchantId;

    @Value("${upp.cashStageMerchantKey}")
    private String cashStageMerchantKey;

    @Autowired
    private OpenApiNetService openApiNetService;

//    @Autowired
//    private UppCore uppCore;

    /**
     * 预下单
     */
    @ApiOperation(value = "预下单")
    @PostMapping(value = "cashStage")
    @ResponseBody
    public String cashStage(@RequestBody PayParamVO payParamVO) {
        Map<String, String> headers = new HashMap<>();
        Map<String, String> param = new TreeMap<>();
        if(StringUtils.isNotEmpty(payParamVO.getMerchantId())) {
            param.put("merchantId", payParamVO.getMerchantId());
            headers.put("merchantId", payParamVO.getMerchantId());
        }
        if(StringUtils.isNotEmpty(payParamVO.getMerchantOrderId())) {
            param.put("merchantOrderId", payParamVO.getMerchantOrderId());
        }
        if(StringUtils.isNotEmpty(payParamVO.getAmount())) {
            param.put("amount", payParamVO.getAmount());
        }
        if(StringUtils.isNotEmpty(payParamVO.getOpenid())) {
            param.put("openid", payParamVO.getOpenid());
        }
//        if(StringUtils.isNotEmpty(payParamVO.getUserId())) {
//            param.put("userId", payParamVO.getUserId());
//        }
//        if(StringUtils.isNotEmpty(payParamVO.getLegderType())) {
//            param.put("legderType", payParamVO.getLegderType());
//        }
//        if(StringUtils.isNotEmpty(payParamVO.getAppId())) {
//            param.put("appId", payParamVO.getAppId());
//        }
//        if(StringUtils.isNotEmpty(payParamVO.getSersuborder())) {
//            param.put("sersuborder", payParamVO.getSersuborder());
//        }
//        if(StringUtils.isNotEmpty(payParamVO.getBankClearNotifyUrl())) {
//            param.put("bankClearNotifyUrl", payParamVO.getBankClearNotifyUrl());
//        }
        if(StringUtils.isNotEmpty(payParamVO.getPeriod())) {
            param.put("period", payParamVO.getPeriod());
        }
        if(StringUtils.isNotEmpty(payParamVO.getPeriodUnit())) {
            param.put("periodUnit", payParamVO.getPeriodUnit());
        }
        if(StringUtils.isNotEmpty(payParamVO.getCallbackUrl())) {
            param.put("callbackUrl", payParamVO.getCallbackUrl());
        }
        if(StringUtils.isNotEmpty(payParamVO.getNotifyUrl())) {
            param.put("notifyUrl", payParamVO.getNotifyUrl());
        }
        if(StringUtils.isNotEmpty(payParamVO.getProductName())) {
            param.put("productName", payParamVO.getProductName());
        }
        if(StringUtils.isNotEmpty(payParamVO.getClientIp())) {
            param.put("clientIp", payParamVO.getClientIp());
        }
        if(StringUtils.isNotEmpty(payParamVO.getOrderCreateDateTime())) {
            param.put("orderCreateDateTime", payParamVO.getOrderCreateDateTime());
        } else {
            param.put("orderCreateDateTime", DateFormatUtil.DateToString(new Date(), DateFormatUtil.YYYYMMDDHHMM));
        }
        String hmac = UppCore.getHmac(param, cashStageMerchantKey, "UTF-8");
        param.put("hmac", hmac);
        log.info("访问开放平台输入:" + param);
        String cashStageResult = (String)openApiNetService.execute(param, headers, openApiNetService.getOpenApiStringClient(jsdSavePayParamUrl, "0.0.1"));
        log.info("访问开放平台输出:" + cashStageResult);
        return cashStageResult;
    }

    /**
     * 订单操作(查询）
     *
     * @return
     */
    @ApiOperation(value = "订单操作(查询）")
    @PostMapping(value = "cashStagePayQuery")
    public String cashStagePayQuery(@RequestBody PayQueryVO payQueryVO) throws Exception {
        Map<String, String> headers = new HashMap<>();
        Map<String, String> param = new TreeMap<>();
        if(StringUtils.isNotEmpty(payQueryVO.getMerchantId())) {
            param.put("merchantId", payQueryVO.getMerchantId());
            headers.put("merchantId", payQueryVO.getMerchantId());
        }
        param.put("type", "orderQuery");
        if(StringUtils.isNotEmpty(payQueryVO.getMerchantOrderId())) {
            param.put("merchantOrderId", payQueryVO.getMerchantOrderId());
            param.put("orderId", payQueryVO.getMerchantOrderId());
            param.put("payNo", payQueryVO.getMerchantOrderId());
        }
        param.put("version", "2.0.0");
        String hmac = UppCore.getHmac(param, cashStageMerchantKey, "UTF-8");
        param.put("hmac", hmac);
        log.info("访问开放平台输入:" + param);
        String payQueryData = (String)openApiNetService.execute(param, headers, openApiNetService.getOpenApiStringClient(jsdPayQueryUrl, "0.0.1"));
        log.info("访问开放平台输出:" + payQueryData);
        return payQueryData;
    }

    /**
     * 订单操作(退款）
     * @return
     */
    @ApiOperation(value = "订单操作(退款）")
    @PostMapping(value = "cashStageRefund")
    public String cashStageRefund(@RequestBody RefundVO refundVO) throws Exception {
        Map<String, String> headers = new HashMap<>();
        Map<String, String> param = new TreeMap<>();
        if(StringUtils.isNotEmpty(refundVO.getMerchantId())) {
            param.put("merchantId", refundVO.getMerchantId());
            headers.put("merchantId", refundVO.getMerchantId());
        }
        param.put("type", "orderRefund");
        if(StringUtils.isNotEmpty(refundVO.getOrderId())) {
            param.put("orderId", refundVO.getOrderId());
        }
        param.put("version", "2.0.0");
        if(StringUtils.isNotEmpty(refundVO.getAmount())) {
            param.put("amount", refundVO.getAmount());
        }
        if(StringUtils.isNotEmpty(refundVO.getRefundnotifyurl())) {
            param.put("refundnotifyurl", refundVO.getRefundnotifyurl());
        }
        if(StringUtils.isNotEmpty(refundVO.getPayNo())) {
            param.put("payNo", refundVO.getPayNo());
        }
        if(StringUtils.isNotEmpty(refundVO.getOrderType())) {
            param.put("orderType", refundVO.getOrderType());
        }
        if(StringUtils.isNotEmpty(refundVO.getRefundInfo())) {
            param.put("refundInfo", refundVO.getRefundInfo());
        }
        //生成签名
        String hmac = UppCore.getHmac(param, cashStageMerchantKey, "UTF-8");
        param.put("hmac", hmac);
        log.info("访问开放平台输入:" + param);
        String refundData = (String)openApiNetService.execute(param, headers, openApiNetService.getOpenApiStringClient(jsdRefundUrl, "0.0.1"));
        log.info("访问开放平台输出:" + refundData);
        return refundData;
    }

    /**
     * 微信企业付款
     * @return
     */
    @ApiOperation(value = "微信企业付款")
    @PostMapping(value = "cashStageWithdrawal")
    @ResponseBody
    public String cashStageWithdrawal(@RequestBody WithdrawalVO withdrawalVO) throws Exception {
        Map<String, String> headers = new HashMap<>();
        Map<String, String> param = new TreeMap<>();
        if(StringUtils.isNotEmpty(withdrawalVO.getNotifyUrl())) {
            param.put("notifyUrl", withdrawalVO.getNotifyUrl());
        }
        if(StringUtils.isNotEmpty(withdrawalVO.getMerchantId())) {
            param.put("merchantId", withdrawalVO.getMerchantId());
            headers.put("merchantId", withdrawalVO.getMerchantId());
        }
        if(StringUtils.isNotEmpty(withdrawalVO.getAmount())) {
            param.put("amount", withdrawalVO.getAmount());
        }
        param.put("currency", "RMB");
        if(StringUtils.isNotEmpty(withdrawalVO.getOrderDate())) {
            param.put("orderDate", withdrawalVO.getOrderDate());
        }
        if(StringUtils.isNotEmpty(withdrawalVO.getMerchantOrderId())) {
            param.put("merchantOrderId", withdrawalVO.getMerchantOrderId());
        }
        param.put("merAcDate", withdrawalVO.getOrderDate());
        if(StringUtils.isNotEmpty(withdrawalVO.getProductDesc())) {
            param.put("productDesc", withdrawalVO.getProductDesc());
        }
        if(StringUtils.isNotEmpty(withdrawalVO.getOpenid())) {
            param.put("openid", withdrawalVO.getOpenid());
        }
        param.put("payOrg", "WX_ENTERPRISE_PAY");
        param.put("clientIp", "0.0.0.0");
        //生成签名
        String hmac = UppCore.getHmac(param, cashStageMerchantKey, "UTF-8");
        param.put("hmac", hmac);
        log.info("输入:" + param);
        String refundData = (String)openApiNetService.execute(param, headers, openApiNetService.getOpenApiStringClient(jsdWithdrawalUrl, "0.0.1"));
        log.info("输出:" + refundData);
        return refundData;
    }

    /**
     * 统一支付支付成功回调
     * @return SUCCESS
     */
    @RequestMapping("/payNotifyResult")
    public String payNotifyResult(HttpServletRequest request) {
        log.info(">>>>>>>>>>>>>>>>>>>>>统一支付支付回调参数start>>>>>>>>>>>>>>>>>>>>>>");
        Enumeration enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            log.info(paraName + ": " + request.getParameter(paraName));
        }
        log.info(">>>>>>>>>>>>>>>>>>>>>统一支付支付回调参数end>>>>>>>>>>>>>>>>>>>>>>");
        return "SUCCESS";
    }

    /**
     * 统一支付退款回调
     * @param request http请求
     * @return SUCCESS
     */
    @RequestMapping("/refundNotifyResult")
    public String refundNotifyResult(HttpServletRequest request) {
        log.info(">>>>>>>>>>>>>>>>>>>>>统一支付支付退款回调参数start>>>>>>>>>>>>>>>>>>>>>>");
        Enumeration enu = request.getParameterNames();
        while (enu.hasMoreElements()) {
            String paraName = (String) enu.nextElement();
            log.info(paraName + ": " + request.getParameter(paraName));
        }
        log.info(">>>>>>>>>>>>>>>>>>>>>统一支付支付退款回调参数end>>>>>>>>>>>>>>>>>>>>>>");
        return "SUCCESS";
    }
}
